home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the 3D Game Programming Gurus / gurus.iso / DirectX / dx9sdkcp.exe / SDK (C++) / Bin / DXUtils / Visual Studio 6.0 Wizards / Source Code / Template / netvoice.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-12  |  29.2 KB  |  784 lines

  1. //-----------------------------------------------------------------------------
  2. // File: NetVoice.cpp
  3. //
  4. // Desc: DirectPlay Voice framework class. Feel free to use 
  5. //       this class as a starting point for adding extra functionality.
  6. //-----------------------------------------------------------------------------
  7. #define STRICT
  8. $$IF(DLG)
  9. #include "stdafx.h"
  10. $$ENDIF
  11. #include <windows.h>
  12. #include <commctrl.h>
  13. #include <dxerr9.h>
  14. #include <dvoice.h>
  15. #include "NetVoice.h"
  16. #include "NetVoiceRes.h"
  17. #include "DXUtil.h"
  18.  
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Global access to the app (needed for the global WndProc())
  22. //-----------------------------------------------------------------------------
  23. static CNetVoice* g_pNetVoice = NULL;
  24.  
  25.  
  26.  
  27.  
  28. //-----------------------------------------------------------------------------
  29. // Name: CNetVoice
  30. // Desc: 
  31. //-----------------------------------------------------------------------------
  32. CNetVoice::CNetVoice( LPDVMESSAGEHANDLER pfnDirectPlayClientVoiceMessageHandler,
  33.                       LPDVMESSAGEHANDLER pfnDirectPlayServerVoiceMessageHandler )
  34. {
  35.     g_pNetVoice = this;
  36.     m_bHalfDuplex  = FALSE;
  37.     m_pVoiceClient = NULL;
  38.     m_pVoiceServer = NULL;
  39.     m_bVoiceSessionInProgress = FALSE;
  40.     m_pfnDirectPlayClientVoiceMessageHandler = pfnDirectPlayClientVoiceMessageHandler;
  41.     m_pfnDirectPlayServerVoiceMessageHandler = pfnDirectPlayServerVoiceMessageHandler;
  42. }
  43.  
  44.  
  45.  
  46.  
  47. //-----------------------------------------------------------------------------
  48. // Name: ~CNetVoice
  49. // Desc: 
  50. //-----------------------------------------------------------------------------
  51. CNetVoice::~CNetVoice()
  52. {
  53.     Free();
  54. }
  55.  
  56.  
  57.  
  58.  
  59. //-----------------------------------------------------------------------------
  60. // Name: Init()
  61. // Desc: Initializes DirectPlay Voice.  
  62. // Params:  hDlg: the HWND of the parent window for use by the voice setup wizard
  63. //          bCreateSession:     if TRUE then it creates the DirectPlay Voice sesson.
  64. //          bConnectToSession:  if TRUE then it connects to the DirectPlay Voice
  65. //                              session.  
  66. //          pDirectPlay:        inteface to the IDirectPlay8Client or 
  67. //                              IDirectPlay8Peer interface 
  68. //          pGuidCT:            guid of the voice compression codec
  69. //          pdvClientConfig:    client config. Can be NULL if bConnectToSession is FALSE.
  70. //          lpds:               pointer to an existing DirectSound object, or NULL 
  71. //                              if none exists yet.
  72. //-----------------------------------------------------------------------------
  73. HRESULT CNetVoice::Init( HWND hDlg, BOOL bCreateSession, BOOL bConnectToSession,
  74.                          LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  75.                          GUID* pGuidCT, DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  76. {
  77.     HRESULT hr;
  78.  
  79.     // Typically the host player creates the voice session 
  80.     if( bCreateSession )
  81.     {
  82.         if( FAILED( hr = VoiceSessionCreate( pDirectPlay, dwSessionType, pGuidCT ) ) )
  83.             return DXTRACE_ERR( TEXT("VoiceSessionCreate"), hr );
  84.     }
  85.  
  86.     if( bConnectToSession )
  87.     {
  88.         // Test the voice setup to make sure the voice setup wizard has been run
  89.         if( FAILED( hr = VoiceSessionTestAudioSetup( hDlg ) ) )
  90.         {
  91.             if( hr == DVERR_USERCANCEL || hr == DVERR_ALREADYPENDING )
  92.                 return hr;
  93.             
  94.             return DXTRACE_ERR( TEXT("VoiceSessionTestAudioSetup"), hr );
  95.         }
  96.  
  97.         // Typically all of the clients connect to the voice session
  98.         if( FAILED( hr = VoiceSessionConnect( hDlg, pDirectPlay, pdvClientConfig, lpds ) ) )
  99.             return DXTRACE_ERR( TEXT("VoiceSessionConnect"), hr );
  100.     }
  101.  
  102.     m_bVoiceSessionInProgress = TRUE;
  103.  
  104.     return S_OK;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. //-----------------------------------------------------------------------------
  111. // Name: Free()
  112. // Desc: Frees DirectPlayVoice
  113. //-----------------------------------------------------------------------------
  114. HRESULT CNetVoice::Free()
  115. {
  116.     HRESULT hr;
  117.  
  118.     if( m_pVoiceClient )
  119.     {
  120.         // Have all the clients disconnect from the session
  121.         if( FAILED( hr = VoiceSessionDisconnect() ) )
  122.             return DXTRACE_ERR( TEXT("VoiceSessionDisconnect"), hr );
  123.     }
  124.  
  125.     if( m_pVoiceServer )
  126.     {
  127.         // Have all the host player destroy the session 
  128.         if( FAILED( hr = VoiceSessionDestroy() ) )
  129.             return DXTRACE_ERR( TEXT("VoiceSessionDestroy"), hr );
  130.     }
  131.  
  132.     return S_OK;
  133. }
  134.  
  135.  
  136.  
  137.  
  138. //-----------------------------------------------------------------------------
  139. // Name: HostMigrate()
  140. // Desc: Starts the DirectPlayVoice session
  141. //       The host player should call this to create the voice session.  It
  142. //       stores the server interface, and addref's it.
  143. //-----------------------------------------------------------------------------
  144. HRESULT CNetVoice::HostMigrate( LPDIRECTPLAYVOICESERVER pdvServerInterface )
  145. {
  146.     if( pdvServerInterface == NULL )
  147.         return E_INVALIDARG;
  148.  
  149.     SAFE_RELEASE( m_pVoiceServer );
  150.  
  151.     m_pVoiceServer = pdvServerInterface;
  152.  
  153.     // Addref the server since we are storing the pointer.
  154.     m_pVoiceServer->AddRef();
  155.  
  156.     return S_OK;
  157. }
  158.  
  159.  
  160.  
  161.  
  162. //-----------------------------------------------------------------------------
  163. // Name: VoiceSessionTestAudioSetup()
  164. // Desc: Uses IDirectPlayVoiceSetup to test the voice setup.
  165. //       All clients should call this once to test the voice audio setup.
  166. //-----------------------------------------------------------------------------
  167. HRESULT CNetVoice::VoiceSessionTestAudioSetup( HWND hDlg )
  168. {
  169.     HRESULT hr;
  170.     LPDIRECTPLAYVOICETEST pVoiceSetup = NULL;
  171.  
  172.     // Create a DirectPlayVoice setup interface.
  173.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceTest, NULL, 
  174.                                        CLSCTX_INPROC_SERVER,
  175.                                        IID_IDirectPlayVoiceTest, 
  176.                                        (LPVOID*) &pVoiceSetup) ) )
  177.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  178.  
  179.     // Check to see if the audio tests have been run yet
  180.     GUID guidPlayback = DSDEVID_DefaultVoicePlayback;
  181.     GUID guidCapture  = DSDEVID_DefaultVoiceCapture;
  182.     hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, 
  183.                                        &guidCapture, 
  184.                                        hDlg, DVFLAGS_QUERYONLY );
  185.     if( hr == DVERR_RUNSETUP )
  186.     {
  187.         // Perform the audio tests, since they need to be done before 
  188.         // any of the DPVoice calls will work.
  189.         hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, &guidCapture, hDlg, DVFLAGS_ALLOWBACK );
  190.         if( FAILED(hr) )
  191.         {
  192.             SAFE_RELEASE( pVoiceSetup );
  193.             
  194.             if( hr == DVERR_USERCANCEL || hr == DVERR_ALREADYPENDING )
  195.                 return hr;
  196.             
  197.             return DXTRACE_ERR( TEXT("CheckAudioSetup"), hr );
  198.         }
  199.     }
  200.  
  201.     // Done with setup
  202.     SAFE_RELEASE( pVoiceSetup );
  203.  
  204.     return hr;
  205. }
  206.  
  207.  
  208.  
  209.  
  210. //-----------------------------------------------------------------------------
  211. // Name: VoiceSessionCreate()
  212. // Desc: Starts the DirectPlayVoice session
  213. //       The host player should call this to create the voice session.
  214. //-----------------------------------------------------------------------------
  215. HRESULT CNetVoice::VoiceSessionCreate( LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  216.                                        GUID* pGuidCT )
  217. {
  218.     HRESULT hr;
  219.  
  220.     // Create a DirectPlayVoice server interface.
  221.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceServer, NULL, 
  222.                                        CLSCTX_INPROC_SERVER,
  223.                                        IID_IDirectPlayVoiceServer, 
  224.                                        (LPVOID*) &m_pVoiceServer ) ) )
  225.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  226.  
  227.     // Init the DirectPlayVoice server
  228.     if( FAILED( hr = m_pVoiceServer->Initialize( pDirectPlay, m_pfnDirectPlayServerVoiceMessageHandler, 
  229.                                                  NULL, 0, 0 ) ) )
  230.         return DXTRACE_ERR( TEXT("Initialize"), hr );
  231.  
  232.     // Setup and start a DirectPlay session based on globals set by user choices 
  233.     // in the config dlg box.
  234.     DVSESSIONDESC dvSessionDesc;
  235.     ZeroMemory( &dvSessionDesc, sizeof(DVSESSIONDESC) );
  236.     dvSessionDesc.dwSize                 = sizeof( DVSESSIONDESC );
  237.     dvSessionDesc.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  238.     dvSessionDesc.dwBufferQuality        = DVBUFFERQUALITY_DEFAULT;
  239.     dvSessionDesc.dwFlags                = 0;
  240.     dvSessionDesc.dwSessionType          = dwSessionType;
  241.     dvSessionDesc.guidCT                 = *pGuidCT;
  242.  
  243.     if( FAILED( hr = m_pVoiceServer->StartSession( &dvSessionDesc, 0 ) ) )
  244.         return DXTRACE_ERR( TEXT("StartSession"), hr );
  245.  
  246.     return S_OK;
  247. }
  248.  
  249.  
  250.  
  251.  
  252. //-----------------------------------------------------------------------------
  253. // Name: VoiceSessionConnect()
  254. // Desc: Connects to the DirectPlayVoice session.  
  255. ///      All clients should call this once to join the voice session.
  256. //-----------------------------------------------------------------------------
  257. HRESULT CNetVoice::VoiceSessionConnect( HWND hDlg, LPUNKNOWN pDirectPlay, 
  258.                                         DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  259. {
  260.     HRESULT hr;
  261.     DVSOUNDDEVICECONFIG  dvSoundDeviceConfig  = {0};
  262.     DVSOUNDDEVICECONFIG* pdvSoundDeviceConfig = NULL;
  263.     
  264.  
  265.     // Create a DirectPlayVoice client interface.
  266.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  267.                                        CLSCTX_INPROC_SERVER,
  268.                                        IID_IDirectPlayVoiceClient, 
  269.                                        (LPVOID*) &m_pVoiceClient ) ) )
  270.     {
  271.         DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
  272.         goto LCleanReturn;
  273.     }
  274.  
  275.     // Init the DirectPlayVoice client, passing in VoiceMessageHandler() as the
  276.     // callback handler for any messages sent to us.
  277.     if( FAILED( hr = m_pVoiceClient->Initialize( pDirectPlay, 
  278.                                                  m_pfnDirectPlayClientVoiceMessageHandler, 
  279.                                                  (LPVOID*) hDlg, // context value
  280.                                                  0, 0 ) ) )
  281.     {
  282.          DXTRACE_ERR_MSGBOX( TEXT("Initialize"), hr );
  283.          goto LCleanReturn;
  284.     }
  285.  
  286.     // Setup the DirectPlayVoice sound devices.  This just uses the defaults.
  287.     dvSoundDeviceConfig.dwSize                    = sizeof( DVSOUNDDEVICECONFIG );
  288.     dvSoundDeviceConfig.dwFlags                   = 0;
  289.     dvSoundDeviceConfig.guidPlaybackDevice        = DSDEVID_DefaultVoicePlayback; 
  290.     dvSoundDeviceConfig.lpdsPlaybackDevice        = lpds;
  291.     dvSoundDeviceConfig.guidCaptureDevice         = DSDEVID_DefaultVoiceCapture; 
  292.     dvSoundDeviceConfig.lpdsCaptureDevice         = NULL;
  293.     dvSoundDeviceConfig.hwndAppWindow             = hDlg;
  294.     dvSoundDeviceConfig.lpdsMainBuffer            = NULL;
  295.     dvSoundDeviceConfig.dwMainBufferFlags         = 0;
  296.     dvSoundDeviceConfig.dwMainBufferPriority      = 0;
  297.  
  298.     // Connect to the voice session
  299.     if( FAILED( hr = m_pVoiceClient->Connect( &dvSoundDeviceConfig, 
  300.                                               pdvClientConfig, 
  301.                                               DVFLAGS_SYNC ) ) )
  302.     {
  303.         DXTRACE_ERR_MSGBOX( TEXT("Connect"), hr );
  304.         goto LCleanReturn;
  305.     }
  306.         
  307.     // Talk to everyone in the session
  308.     DVID dvid;
  309.     dvid = DVID_ALLPLAYERS;
  310.     if( FAILED( hr = m_pVoiceClient->SetTransmitTargets( &dvid, 1, 0 ) ) )
  311.     {
  312.         DXTRACE_ERR_MSGBOX( TEXT("SetTransmitTargets"), hr );
  313.         goto LCleanReturn;
  314.     }
  315.  
  316.     // Get the sound device config and extract if its half duplex
  317.     DWORD dwSize;
  318.     dwSize = 0;
  319.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  320.     if( FAILED(hr) && hr != DVERR_BUFFERTOOSMALL )
  321.     {
  322.         DXTRACE_ERR_MSGBOX( TEXT("GetSoundDeviceConfig"), hr );
  323.         goto LCleanReturn;
  324.     }
  325.  
  326.     pdvSoundDeviceConfig = (DVSOUNDDEVICECONFIG*) new BYTE[ dwSize ];
  327.     if( NULL == pdvSoundDeviceConfig )
  328.     {
  329.         hr = E_OUTOFMEMORY;
  330.         DXTRACE_ERR_MSGBOX( TEXT("VoiceSessionConnect"), hr );
  331.         goto LCleanReturn;
  332.     }
  333.  
  334.     ZeroMemory( pdvSoundDeviceConfig, dwSize );
  335.     pdvSoundDeviceConfig->dwSize = sizeof(DVSOUNDDEVICECONFIG);
  336.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  337.     if( FAILED(hr) )
  338.     {
  339.         DXTRACE_ERR_MSGBOX( TEXT("GetSoundDeviceConfig"), hr );
  340.         goto LCleanReturn;
  341.     }
  342.  
  343.     m_bHalfDuplex = ( (pdvSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_HALFDUPLEX) != 0 );
  344.     
  345.     hr = S_OK;
  346.  
  347. LCleanReturn:
  348.     SAFE_DELETE_ARRAY( pdvSoundDeviceConfig );
  349.  
  350.     return hr;
  351. }
  352.  
  353.  
  354.  
  355.  
  356. //-----------------------------------------------------------------------------
  357. // Name: ChangeVoiceClientSettings()
  358. // Desc: Changes the client config to globals set by user choices 
  359. //       in the config dlg box.
  360. //-----------------------------------------------------------------------------
  361. HRESULT CNetVoice::ChangeVoiceClientSettings( DVCLIENTCONFIG* pdvClientConfig )
  362. {
  363.     HRESULT hr;
  364.  
  365.     if( m_pVoiceClient == NULL )
  366.         return CO_E_NOTINITIALIZED;
  367.  
  368.     // Change the client config
  369.     if( FAILED( hr = m_pVoiceClient->SetClientConfig( pdvClientConfig) ) )
  370.         return DXTRACE_ERR( TEXT("SetClientConfig"), hr );
  371.  
  372.     return S_OK;
  373. }
  374.  
  375.  
  376.  
  377.  
  378. //-----------------------------------------------------------------------------
  379. // Name: VoiceSessionDisconnect()
  380. // Desc: Disconnects from the DirectPlayVoice session
  381. //       All clients should call this once to leave the voice session.
  382. //-----------------------------------------------------------------------------
  383. HRESULT CNetVoice::VoiceSessionDisconnect()
  384. {
  385.     if( m_pVoiceClient )
  386.     {
  387.         m_pVoiceClient->Disconnect( DVFLAGS_SYNC );
  388.         SAFE_RELEASE( m_pVoiceClient );
  389.     }
  390.  
  391.     return S_OK;
  392. }
  393.  
  394.  
  395.  
  396.  
  397. //-----------------------------------------------------------------------------
  398. // Name: VoiceSessionDestroy()
  399. // Desc: Stops the DirectPlayVoice session
  400. //       The host player should call this once to destroy the voice session.
  401. //-----------------------------------------------------------------------------
  402. HRESULT CNetVoice::VoiceSessionDestroy()
  403. {
  404.     if( m_pVoiceServer )
  405.     {
  406.         m_pVoiceServer->StopSession( 0 );
  407.         SAFE_RELEASE( m_pVoiceServer );
  408.     }
  409.  
  410.     return S_OK;
  411. }
  412.  
  413.  
  414.  
  415.  
  416. //-----------------------------------------------------------------------------
  417. // Name: DoVoiceSetupDialog()
  418. // Desc: 
  419. //-----------------------------------------------------------------------------
  420. HRESULT CNetVoice::DoVoiceSetupDialog( HINSTANCE hInst, HWND hWndParent, GUID* pguidDVSessionCT, DVCLIENTCONFIG* pdvClientConfig )
  421. {
  422.     if( NULL == pguidDVSessionCT || NULL == pdvClientConfig )
  423.         return E_INVALIDARG;
  424.  
  425.     m_guidDVSessionCT = *pguidDVSessionCT;
  426.     m_dvClientConfig = *pdvClientConfig;
  427.  
  428.     // Ask user to change m_dvClientConfig, g_guidDVSessionCT
  429.     DWORD dwResult = (DWORD)DialogBox( hInst, MAKEINTRESOURCE(IDD_VOICE_SETUP), 
  430.                                        hWndParent, (DLGPROC) StaticVoiceConfigDlgProc );
  431.     if( dwResult == IDCANCEL )
  432.         return DVERR_USERCANCEL;
  433.  
  434.     *pguidDVSessionCT = m_guidDVSessionCT;
  435.     *pdvClientConfig = m_dvClientConfig;
  436.  
  437.     return S_OK;
  438. }
  439.  
  440.  
  441.  
  442.  
  443. //-----------------------------------------------------------------------------
  444. // Name: StaticVoiceConfigDlgProc()
  445. // Desc: Static callback helper to call into CNetVoice class
  446. //-----------------------------------------------------------------------------
  447. INT_PTR CALLBACK CNetVoice::StaticVoiceConfigDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  448. {
  449.     if( g_pNetVoice )
  450.         return g_pNetVoice->VoiceConfigDlgProc( hDlg, msg, wParam, lParam );
  451.     return 0;
  452. }
  453.  
  454.  
  455.  
  456.  
  457.  
  458. //-----------------------------------------------------------------------------
  459. // Name: VoiceConfigDlgProc()
  460. // Desc: Prompt the user for DirectPlayVoice setup options
  461. //-----------------------------------------------------------------------------
  462. INT_PTR CALLBACK CNetVoice::VoiceConfigDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  463. {
  464.     DWORD dwSliderPos;
  465.  
  466.     switch( msg ) 
  467.     {
  468.         case WM_INITDIALOG:
  469.             // Set the range on the sliders
  470.             SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER,       TBM_SETRANGE, FALSE, MAKELONG( 0, 100 ) );
  471.             SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER,         TBM_SETRANGE, FALSE, MAKELONG( 0, 100 ) );
  472.             SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER,        TBM_SETRANGE, FALSE, MAKELONG( DVBUFFERQUALITY_MIN, DVBUFFERQUALITY_MAX ) );
  473.             SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER,    TBM_SETRANGE, FALSE, MAKELONG( DVTHRESHOLD_MIN,  DVTHRESHOLD_MAX ) );
  474.             SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_SETRANGE, FALSE, MAKELONG( DVBUFFERAGGRESSIVENESS_MIN, DVBUFFERAGGRESSIVENESS_MAX ) );
  475.  
  476.             // Setup the dialog based on the globals 
  477.  
  478.             // Set the playback controls
  479.             if( m_dvClientConfig.lPlaybackVolume == DVPLAYBACKVOLUME_DEFAULT )
  480.             {
  481.                 CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_DEFAULT );
  482.             }
  483.             else
  484.             {
  485.                 dwSliderPos = (DWORD) ( ( m_dvClientConfig.lPlaybackVolume - DSBVOLUME_MIN ) * 
  486.                                           100.0f / (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  487.                 CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_SET );
  488.                 SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER, TBM_SETPOS, TRUE, dwSliderPos );
  489.             }
  490.  
  491.             // Set the record controls
  492.             if( m_dvClientConfig.dwFlags & DVCLIENTCONFIG_AUTORECORDVOLUME )
  493.             {
  494.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_AUTO );
  495.             }
  496.             else if( m_dvClientConfig.lRecordVolume == DVPLAYBACKVOLUME_DEFAULT )
  497.             {
  498.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_DEFAULT );
  499.             }
  500.             else
  501.             {
  502.                 dwSliderPos = (DWORD) ( ( m_dvClientConfig.lRecordVolume - DSBVOLUME_MIN ) * 
  503.                                           100.0f / (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  504.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_SET );
  505.                 SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER, TBM_SETPOS, TRUE, dwSliderPos );
  506.             }
  507.  
  508.             // Set the threshold controls
  509.             if( m_dvClientConfig.dwFlags & DVCLIENTCONFIG_AUTOVOICEACTIVATED )
  510.             {
  511.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_AUTO );
  512.             }
  513.             else if( m_dvClientConfig.dwThreshold == DVTHRESHOLD_DEFAULT )
  514.             {
  515.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_DEFAULT );
  516.             }
  517.             else
  518.             {
  519.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_SET );
  520.                 SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwThreshold );
  521.             }
  522.  
  523.             // Set the quality controls
  524.             if( m_dvClientConfig.dwBufferQuality == DVBUFFERQUALITY_DEFAULT )
  525.             {
  526.                 CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_DEFAULT );
  527.             }
  528.             else
  529.             {
  530.                 CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_SET );
  531.                 SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwBufferQuality );
  532.             }
  533.  
  534.             // Set the aggressiveness controls
  535.             if( m_dvClientConfig.dwBufferAggressiveness == DVBUFFERAGGRESSIVENESS_DEFAULT )
  536.             {
  537.                 CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_DEFAULT );
  538.             }
  539.             else
  540.             {
  541.                 CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_SET );
  542.                 SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwBufferAggressiveness );
  543.             }
  544.  
  545.             if( !m_bHostPlayer || m_bVoiceSessionInProgress )
  546.             {
  547.                 // We are are not the host player then disable all the server only options 
  548.                 EnableWindow( GetDlgItem( hDlg, IDC_COMPRESSION_COMBO ), FALSE );
  549.                 EnableWindow( GetDlgItem( hDlg, IDC_SESSIONCOMPRESION_GROUP ), FALSE );
  550.             }
  551.             else
  552.             {
  553.                 VoiceConfigEnumCompressionCodecs( hDlg );   
  554.                 EnableWindow( GetDlgItem( hDlg, IDCANCEL ), FALSE );
  555.             }
  556.  
  557.             return TRUE;
  558.  
  559.         case WM_NOTIFY:
  560.             #ifndef NM_RELEASEDCAPTURE
  561.                 #define NM_RELEASEDCAPTURE (NM_FIRST-16)
  562.             #endif
  563.             if( ((LPNMHDR) lParam)->code == NM_RELEASEDCAPTURE )
  564.             {
  565.                 // If this is a release capture from a slider, then automatically check 
  566.                 // its 'Set' radio button.
  567.                 switch( ((LPNMHDR) lParam)->idFrom )
  568.                 {
  569.                 case IDC_PLAYBACK_SLIDER:
  570.                     CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_SET );
  571.                     break;
  572.     
  573.                 case IDC_RECORD_SLIDER:
  574.                     CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_SET );
  575.                     break;
  576.     
  577.                 case IDC_THRESHOLD_SLIDER:
  578.                     CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_SET );
  579.                     break;
  580.     
  581.                 case IDC_QUALITY_SLIDER:
  582.                     CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_SET );
  583.                     break;
  584.     
  585.                 case IDC_AGGRESSIVENESS_SLIDER:
  586.                     CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_SET );
  587.                     break;
  588.                 }
  589.             }
  590.             return TRUE;            
  591.  
  592.         case WM_COMMAND:
  593.             switch( LOWORD(wParam) )
  594.             {
  595.                 case IDOK:
  596.                     VoiceConfigDlgOnOK( hDlg );
  597.                     return TRUE;
  598.  
  599.                 case IDCANCEL:
  600.                     EndDialog( hDlg, IDCANCEL );
  601.                     return TRUE;
  602.             }
  603.             break;
  604.  
  605.         case WM_DESTROY:
  606.         {
  607.             GUID* pGuid;
  608.             int nCount = (int)SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETCOUNT, 0, 0 );
  609.             for( int i=0; i<nCount; i++ )
  610.             {
  611.                 pGuid = (LPGUID) SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETITEMDATA, i, 0 );
  612.                 SAFE_DELETE( pGuid );
  613.             }
  614.             break;
  615.         }
  616.     }
  617.  
  618.     return FALSE; // Didn't handle message
  619. }
  620.  
  621.  
  622.  
  623.  
  624. //-----------------------------------------------------------------------------
  625. // Name: VoiceConfigEnumCompressionCodecs()
  626. // Desc: Asks DirectPlayVoice what voice compression codecs are availible
  627. //       and fills the combo box thier names and GUIDs.
  628. //-----------------------------------------------------------------------------
  629. HRESULT CNetVoice::VoiceConfigEnumCompressionCodecs( HWND hDlg )
  630. {
  631.     LPDIRECTPLAYVOICECLIENT pVoiceClient        = NULL;
  632.     LPDVCOMPRESSIONINFO     pdvCompressionInfo  = NULL;
  633.     LPGUID  pGuid         = NULL;
  634.     LPBYTE  pBuffer       = NULL;
  635.     DWORD   dwSize        = 0;
  636.     DWORD   dwNumElements = 0;
  637.     HWND    hPulldown     = GetDlgItem( hDlg, IDC_COMPRESSION_COMBO );
  638.     HRESULT hr;
  639.     LONG    lIndex;
  640.     LONG    lFirst = 0;
  641.  
  642.     CoInitializeEx( NULL, COINIT_MULTITHREADED );
  643.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  644.                                        CLSCTX_INPROC_SERVER, IID_IDirectPlayVoiceClient, 
  645.                                        (VOID**) &pVoiceClient ) ) )
  646.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  647.  
  648.     hr = pVoiceClient->GetCompressionTypes( pBuffer, &dwSize, &dwNumElements, 0 );
  649.     if( hr != DVERR_BUFFERTOOSMALL && FAILED(hr) )
  650.         return DXTRACE_ERR( TEXT("GetCompressionTypes"), hr );
  651.  
  652.     pBuffer = new BYTE[dwSize];
  653.     if( FAILED( hr = pVoiceClient->GetCompressionTypes( pBuffer, &dwSize, 
  654.                                                         &dwNumElements, 0 ) ) )
  655.         return DXTRACE_ERR( TEXT("GetCompressionTypes"), hr );
  656.  
  657.     SAFE_RELEASE( pVoiceClient );
  658.     CoUninitialize();
  659.  
  660.     pdvCompressionInfo = (LPDVCOMPRESSIONINFO) pBuffer;
  661.     for( DWORD dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
  662.     {
  663.         TCHAR strName[MAX_PATH];
  664.         DXUtil_ConvertWideStringToGenericCch( strName, 
  665.                                            pdvCompressionInfo[dwIndex].lpszName, MAX_PATH );
  666.  
  667.         lIndex = (LONG)SendMessage( hPulldown, CB_ADDSTRING, 0, (LPARAM) strName );
  668.  
  669.         pGuid = new GUID;
  670.         (*pGuid) = pdvCompressionInfo[dwIndex].guidType;
  671.         SendMessage( hPulldown, CB_SETITEMDATA, lIndex, (LPARAM) pGuid );
  672.  
  673.         if( pdvCompressionInfo[dwIndex].guidType == DPVCTGUID_SC03 )
  674.             lFirst = lIndex;
  675.     }
  676.  
  677.     SAFE_DELETE_ARRAY( pBuffer );
  678.     SendMessage( hPulldown, CB_SETCURSEL, lFirst, 0 );
  679.  
  680.     return S_OK;
  681. }
  682.  
  683.  
  684.  
  685.  
  686. //-----------------------------------------------------------------------------
  687. // Name: VoiceConfigDlgOnOK()
  688. // Desc: Figure out all the DirectPlayVoice setup params from the dialog box,
  689. //       and store them in global vars.
  690. //-----------------------------------------------------------------------------
  691. VOID CNetVoice::VoiceConfigDlgOnOK( HWND hDlg )
  692. {
  693.     DWORD dwSliderPos;
  694.  
  695.     m_dvClientConfig.dwFlags = 0;
  696.  
  697.     // Figure out the playback params
  698.     if( IsDlgButtonChecked( hDlg, IDC_PLAYBACK_DEFAULT ) )
  699.     {
  700.         m_dvClientConfig.lPlaybackVolume = DVPLAYBACKVOLUME_DEFAULT;
  701.     }
  702.     else 
  703.     {
  704.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER, TBM_GETPOS, 0, 0 );
  705.         m_dvClientConfig.lPlaybackVolume = DSBVOLUME_MIN + (LONG) ( dwSliderPos / 100.0f * 
  706.                                                                     (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  707.     }
  708.  
  709.     // Figure out the record params
  710.     if( IsDlgButtonChecked( hDlg, IDC_RECORD_AUTO ) )
  711.     {
  712.         m_dvClientConfig.lRecordVolume = 0;
  713.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_AUTORECORDVOLUME;
  714.     }
  715.     else if( IsDlgButtonChecked( hDlg, IDC_RECORD_DEFAULT ) )
  716.     {
  717.         m_dvClientConfig.lRecordVolume = DVPLAYBACKVOLUME_DEFAULT;
  718.     }
  719.     else 
  720.     {
  721.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER, TBM_GETPOS, 0, 0 );
  722.         m_dvClientConfig.lRecordVolume = DSBVOLUME_MIN + (LONG) ( dwSliderPos / 100.0f * 
  723.                                                                   (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  724.     }
  725.  
  726.     // Figure out the threshold params
  727.     if( IsDlgButtonChecked( hDlg, IDC_THRESHOLD_AUTO ) )
  728.     {
  729.         m_dvClientConfig.dwThreshold = DVTHRESHOLD_UNUSED;
  730.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_AUTOVOICEACTIVATED;
  731.     }
  732.     else if( IsDlgButtonChecked( hDlg, IDC_THRESHOLD_DEFAULT ) )
  733.     {
  734.         m_dvClientConfig.dwThreshold = DVTHRESHOLD_DEFAULT;
  735.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_MANUALVOICEACTIVATED;
  736.     }
  737.     else 
  738.     {
  739.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER, TBM_GETPOS, 0, 0 );
  740.         m_dvClientConfig.dwThreshold = dwSliderPos;
  741.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_MANUALVOICEACTIVATED;
  742.     }
  743.  
  744.     // Figure out the quality params
  745.     if( IsDlgButtonChecked( hDlg, IDC_QUALITY_DEFAULT ) )
  746.     {
  747.         m_dvClientConfig.dwBufferQuality = DVBUFFERQUALITY_DEFAULT;
  748.     }
  749.     else 
  750.     {
  751.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER, TBM_GETPOS, 0, 0 );
  752.         m_dvClientConfig.dwBufferQuality = dwSliderPos;
  753.     }
  754.  
  755.     // Figure out the aggressiveness params
  756.     if( IsDlgButtonChecked( hDlg, IDC_AGGRESSIVENESS_DEFAULT ) )
  757.     {
  758.         m_dvClientConfig.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  759.     }
  760.     else 
  761.     {
  762.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_GETPOS, 0, 0 );
  763.         m_dvClientConfig.dwBufferAggressiveness = dwSliderPos;
  764.     }
  765.  
  766.     if( m_bHostPlayer )
  767.     {
  768.         // Figure out the compression codec
  769.         LONG lCurSelection;
  770.         LPGUID pGuidCT;
  771.  
  772.         lCurSelection = (LONG)SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETCURSEL, 0, 0 );
  773.         if( lCurSelection != CB_ERR )
  774.         {
  775.             pGuidCT = (LPGUID) SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, 
  776.                                                    CB_GETITEMDATA, lCurSelection, 0 );
  777.             if( pGuidCT != NULL )
  778.                 m_guidDVSessionCT = (*pGuidCT);
  779.         }
  780.     }
  781.  
  782.     EndDialog( hDlg, IDOK );
  783. }
  784.